"""
@Filename: tools/unification_request
@Author: yoko
@Time: 2023/3/28 14:10
@Describe: ...
"""
import logging
import re
from io import StringIO


import allure
import requests
import yaml


from tools.assert_util import total_assert
from tools.operate_ini import load_ini
from tools.operate_yaml import extract_expression
from tools.tool_funs import Tool

session=requests.session()
#通过文件名获得日志对象
logger=logging.getLogger(__name__)
class RequestUtil:
    # 封装统一请求
    def uniform_request(self,caseinfo,base_url):
        # 统一编写yaml标准
        # yaml文件一级目录包含“title,request,validate"
        keys_list=caseinfo.keys()
        print(f"{keys_list=}")
        if set(keys_list).issuperset({'feature','story','title', 'request', 'validate'}):
            # 判断request的一级目录包含method，url
            req_keys_list=caseinfo["request"].keys()
            if set(req_keys_list).issuperset({'method','url'}):
                # 热加载
                caseinfo = RequestUtil().hot_loading(caseinfo)
                logger.info(f"-----{caseinfo['title']}开始执行--------")
                allure.dynamic.title(caseinfo['title'])
                if "https:" not in caseinfo['request']['url']:
                    caseinfo['request']['url']= base_url + caseinfo['request']['url']

                print(caseinfo["request"].keys())
                # 判断request是否有写到headers,从pytest获取参数加到headers里
                if "headers" in caseinfo["request"].keys():
                    logger.info("用例请求头：%s" % caseinfo["request"]["headers"])
                    if caseinfo["request"]["headers"]=="None":
                        caseinfo["request"]["headers"]=load_ini()
                        logger.info("用例请求头：%s" % caseinfo["request"]["headers"])
                validate = caseinfo['validate']
                print(f"{caseinfo=}")
                # 加入日志
                logger.info("用例标题：%s" % caseinfo["title"])
                logger.info("请求方式：%s" % caseinfo["request"]["method"])
                logger.info("请求的url路径：%s" % caseinfo["request"]["url"])
                if "params" in caseinfo["request"].keys():
                    logger.info("用例params：%s" % caseinfo["request"]["params"])
                if "body" in caseinfo["request"].keys():
                    logger.info("用例body：%s" % caseinfo["request"]["body"])

                res=self.send_all_request(**caseinfo['request'])
                print(res.text)
                if "extract" in keys_list:
                    extract_expression(res,caseinfo)
                total_assert(validate, res)
                logger.info(f"-----{caseinfo['title']}执行结束--------")
                logger.info("预期结果：%s" % caseinfo["validate"])
                logger.info("实际结果：%s" % res.text)
                # return res
            else:
                print("yaml文件不符标准要求request的一级目录不包含method，url")
                logger.info("yaml文件不符标准要求request的一级目录不包含method，url")
        else:
            print("yaml文件不符标准要求，一级目录中不包含title或request或validate或feature或story")
            logger.info("request的一级目录不包含method，url")

    # 封装的统一发送请求的方法
    def send_all_request(self, **kwargs):
        return session.request(**kwargs)
    #热加载
    def hot_loading(self,caseinfo):
        yam_str=yaml.dump(caseinfo)
        print(yam_str)
        #正则提取
        fun_list=re.findall('\\$\\{(.*?)\\((.*?)\\)\\}',yam_str)
        # fun_list是一个列表元组的形式，所以使用for循环遍历[('md5_encode', 'q123456')]
        print(f"{fun_list=}")
        for fun in fun_list:

            old_str="${"+fun[0]+"("+fun[1]+")}"
            if "," not in fun[1]:
                new_str=getattr(Tool(),fun[0])(fun[1])
            else:
                arg=fun[1].split(",")
                new_str=getattr(Tool(),fun[0])(*arg)
            print(f"{new_str=}")
            yam_str=yam_str.replace(old_str,new_str)
        caseinfo=yaml.safe_load(StringIO(yam_str))
        return caseinfo

